package cn.ryh.security.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * Security 配置类
 * @author Rao
 * @Description
 * @create 2022-04-13 13:50
 */

@EnableWebSecurity
public class SecurltyConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 设置首页所有人可以访问，功能页有权限的才能进行访问
        http.authorizeRequests()
                .antMatchers("/","/index").permitAll()
                // 拥有vip1角色的才能访问 /level1/**
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        // 没有权限默认跳转到登录页面  /login
        http.formLogin()
                // 设置自定义登录页
                .loginPage("/login")
                // 设置登录
                .loginProcessingUrl("login");
        // 开启注销功能
        http.logout()
                .logoutSuccessUrl("/login");
        // 开启记住我功能,cookie 默认保存14天
        http.rememberMe();
    }

    /**
     * 认证
     * 在Springboot 2.1.x 可以直接使用
     * 在Spring security 5.0+ 会提示 There is no PasswordEncoder mapped for the id "null"
     * 所以需要设置加密方式 (其 Spring security 5.0 自己有很多内置的加密方法)
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /*
         会报There is no PasswordEncoder mapped for the id "null错误
         auth.inMemoryAuthentication()
                 .withUser("ryh").password("123456").roles("vip2","vip3")
                 .and()
                 .withUser("root").password("123456").roles("vip1","vip2","vip3");
        */
        // 这些用户数据应该从数据库中读取
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("ryh").password(new BCryptPasswordEncoder().encode("123456"))
                    .roles("vip2","vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456"))
                    .roles("vip1","vip2","vip3");
    }
}
